package br.com.android.financas.fragments;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import br.com.android.financas.MesTotal;
import br.com.android.financas.R;
import br.com.android.financas.activities.HomeDespesa;
import br.com.android.financas.activities.HomePoupanca;
import br.com.android.financas.activities.HomeReceita;
import br.com.android.financas.adapter.CategoriaSpinnerAdapter;
import br.com.android.financas.adapter.ListaDespesasMensaisAdapter;
import br.com.android.financas.model.Apresentavel;
import br.com.android.financas.model.Categoria;
import br.com.android.financas.model.Despesa;
import br.com.android.financas.model.Poupanca;
import br.com.android.financas.model.Receita;
import br.com.android.financas.repositorio.RepositorioCategoria;
import br.com.android.financas.repositorio.RepositorioDespesa;
import br.com.android.financas.repositorio.RepositorioPoupanca;
import br.com.android.financas.repositorio.RepositorioReceita;
import br.com.android.financas.repositorio.impl.RepositorioCategoriaImpl;
import br.com.android.financas.repositorio.impl.RepositorioDespesaImpl;
import br.com.android.financas.repositorio.impl.RepositorioPoupancaImpl;
import br.com.android.financas.repositorio.impl.RepositorioReceitaImpl;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.ActionMode;

public class ListaDespesas extends SherlockFragment {
	private ActionMode mMode;
	private ExpandableListView expListView;
	private RepositorioDespesa repositorioDespesa;
	private Map<MesTotal, List<Apresentavel>> mesesTotais;
	private Despesa despesa;
	private Receita receita;
	private Poupanca poupanca;
	private ListaDespesasMensaisAdapter expListAdapter;
	private Spinner campoCategoria;
	private RepositorioCategoria repositorioCategoria;
	private RepositorioReceita repositorioReceita;
	private RepositorioPoupanca repositorioPoupanca;
	private OnChangeListener mListener;
	private boolean changed;
	private Intent intent;
	private View selecionado;
	private Categoria categoria,categoriaCarregada;
	//private List<Apresentavel> apagados=new ArrayList<Apresentavel>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		loadRepositorios(getActivity());

		campoCategoria = (Spinner) getView().findViewById(
				R.listaDespesa.categoria);
		expListView = (ExpandableListView) getView().findViewById(
				R.listaDespesa.lista);

		expListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

		expListView.setOnChildClickListener(new OnChildClickListener() {

			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				final Object selected = expListAdapter.getChild(groupPosition,
						childPosition);

				if(selecionado!=null){
					limparSelecionado();
					mMode.finish();
					return false;
				}

				if (selected instanceof Despesa) {
					// HomeDespesa.callMe(getActivity(), (Integer)
					// ((Despesa)selected).getId());
					intent = new Intent(getActivity(), HomeDespesa.class);
					intent.putExtra("id",
							(Integer) ((Despesa) selected).getId());
					startActivityForResult(intent, 1);
				} else if (selected instanceof Receita) {
					// HomeReceita.callMe(getActivity(), (Integer)
					// ((Receita)selected).getId());
					intent = new Intent(getActivity(), HomeReceita.class);
					intent.putExtra("id",
							(Integer) ((Receita) selected).getId());
					startActivityForResult(intent, 1);
				} else {
					intent = new Intent(getActivity(), HomePoupanca.class);
					intent.putExtra("id",
							(Integer) ((Poupanca) selected).getId());
					startActivityForResult(intent, 1);
					// HomePoupanca.callMe(getActivity(), (Integer)
					// ((Poupanca)selected).getId());

				}

				return true;
			}
		});

		expListView
				.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

					@Override
					public boolean onItemLongClick(AdapterView<?> adapter,
							View view, int position, long l) {
						try {

							limparSelecionado();
							selecionado=view;
							view.setBackgroundResource(android.R.color.holo_blue_light);

							Object t = expListView.getAdapter().getItem(position);
							//apagados.add((Apresentavel) t);
							if (t instanceof Despesa) {
								despesa = (Despesa) t;
							} else if (t instanceof Receita)
								receita = (Receita) t;
							else
								poupanca = (Poupanca) t;

							mMode = getSherlockActivity().startActionMode(
									new ExcluirApresentaval());


						} catch (Exception e) {
						}
						return true;
					}
				});

		expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {

			@Override
					public void onGroupExpand(int groupPosition) {

						if (expListAdapter.getChildren(groupPosition).size() == 0 || changed) {
							MesTotal mes= null;
							if (categoria != null && categoriaCarregada != null) {
								if (!categoria.equals(categoriaCarregada)){
									expListAdapter.setMesesTotais(getValores(categoria));
									mes=expListAdapter.getGroup(expListAdapter.getMesCorrente());
								}
							} else {
								if (categoria == null && categoriaCarregada != null) {
									expListAdapter.setMesesTotais(getValores(null));
									mes=expListAdapter.getGroup(expListAdapter.getMesCorrente());
								} else if (categoria != null && categoriaCarregada == null) {
									expListAdapter.setMesesTotais(getValores(categoria));
									mes=expListAdapter.getGroup(expListAdapter.getMesCorrente());

								}
							}

							if(mes==null)
								mes=expListAdapter.getGroup(groupPosition);

							expListAdapter.carregaItens(mes, categoria);
							expListAdapter.notifyDataSetChanged();
							changed = false;

							if(expListAdapter.getMesCorrente()!=groupPosition)
								expListView.expandGroup(expListAdapter.getMesCorrente());
						}

					}
		});

		campoCategoria
				.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View item,
							int i, long l) {
						categoria = (Categoria) arg0.getAdapter()
								.getItem(i);
						if(categoria.getId()==null)
							categoria=null;
						changed=true;
						expListView.expandGroup(expListAdapter.getMesCorrente(), true);
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
						// TODO Auto-generated method stub

					}
				});
	}

	private void limparSelecionado(){
		if(selecionado!=null){
			selecionado.setBackgroundResource(android.R.color.transparent);

		}
		selecionado=null;
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.lista_despesas, container, false);
		return view.findViewById(R.listaDespesa.layout);
	}

	public void loadRepositorios(Activity activity) {
		try {
			repositorioDespesa = new RepositorioDespesaImpl(activity);
			repositorioCategoria = new RepositorioCategoriaImpl(activity);
			repositorioReceita = new RepositorioReceitaImpl(activity);
			repositorioPoupanca = new RepositorioPoupancaImpl(activity);
		} catch (SQLException e) {
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		if (changed || mesesTotais == null)
			loadData();
	}

	public void setChanged(boolean changed) {
		this.changed = changed;
	}

	public boolean isChanged() {
		return changed;
	}

	public void loadData() {
		expListAdapter = new ListaDespesasMensaisAdapter(getActivity(),	getValores(null));

		expListView.setAdapter(expListAdapter);
		if(expListView.getCount()>0){
			expListAdapter.carregaItens(expListAdapter.getGroup(expListAdapter.getMesCorrente()),null);
			expListView.expandGroup(expListAdapter.getMesCorrente(), true);
		}
		ArrayAdapter<Categoria> adapter = new CategoriaSpinnerAdapter(
				getActivity(), R.layout.cor_item,
				repositorioCategoria.listar(), getActivity().getString(
						R.string.todas));
		campoCategoria.setAdapter(adapter);

	}


	public Map<MesTotal, List<Apresentavel>> getValores(Categoria categoria) {

		if (mesesTotais == null || changed) {
			mesesTotais=new HashMap<MesTotal, List<Apresentavel>>();
			List<MesTotal> totais=new ArrayList<MesTotal>();
			List<MesTotal> totaisR =new ArrayList<MesTotal>();
			if(categoria!=null && categoria.getId()!=null){
				totais= repositorioDespesa.getTotaisMensais(categoria);

			}else{
				totais= repositorioDespesa.getTotaisMensais();
				totais.addAll(repositorioPoupanca.getTotaisMensais());
				totaisR =repositorioReceita.getTotaisMensais();
			}
			categoriaCarregada=categoria;

			Map<MesTotal, Double> tmp=new HashMap<MesTotal, Double>();
			Map<MesTotal, Double> tmpR=new HashMap<MesTotal, Double>();

			for(MesTotal mes: totais){
				if(!tmp.containsKey(mes))
					tmp.put(mes, mes.getTotal());
				else{
					tmp.put(mes,tmp.get(mes)+mes.getTotal());
				}
			}
			for(MesTotal mes: totaisR){
				if(!tmpR.containsKey(mes))
					tmpR.put(mes, mes.getTotal());
				else{
					tmpR.put(mes,tmpR.get(mes)-mes.getTotal());
				}
			}

			Set<MesTotal> meses=tmp.keySet();

			for(MesTotal mes: meses){
				double receita = tmpR.containsKey(mes)?tmpR.get(mes):0;
				double despesa = tmp.containsKey(mes)?tmp.get(mes):0;
				if(categoria!=null && categoria.getId()!=null){
					mes.setTotal(despesa);
				}
				else{
					mes.setTotal(receita-despesa);
				}

				mesesTotais.put(mes, new ArrayList<Apresentavel>());
			}

		}
		changed = false;
		return mesesTotais;

	}

	private final class ExcluirApresentaval implements
			ActionMode.Callback {

		@Override
		public void onDestroyActionMode(ActionMode mode) {
		}

		@Override
		public boolean onCreateActionMode(ActionMode mode,
				com.actionbarsherlock.view.Menu menu) {
			menu.add(R.string.apagar).setIcon(R.drawable.trash)
					.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

			return true;
		}

		@Override
		public boolean onPrepareActionMode(ActionMode mode,
				com.actionbarsherlock.view.Menu menu) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public boolean onActionItemClicked(ActionMode mode,
				final com.actionbarsherlock.view.MenuItem item) {
			// Toast.makeText(getActivity(),"Got click: " + item + " - " +
			// despesa.getDescricao(), Toast.LENGTH_SHORT).show();

			AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

			LayoutInflater factory = LayoutInflater.from(getActivity());
			View layout = factory.inflate(R.layout.apagar_despesa, null);
			final CheckBox todas = (CheckBox) layout
					.findViewById(R.apagar.todasGrupo);
			final CheckBox frente = (CheckBox) layout
					.findViewById(R.apagar.paraFrente);

			if ((despesa != null && (despesa.isPai() || despesa.getPai() != null))
					|| (receita != null && (receita.isPai() || receita.getPai() != null))) {

				todas.setOnCheckedChangeListener(new OnCheckedChangeListener() {

					@Override
					public void onCheckedChanged(CompoundButton arg0,
							boolean check) {
						if (check) {
							frente.setVisibility(View.INVISIBLE);
						} else
							frente.setVisibility(View.VISIBLE);
					}
				});

				builder.setView(layout);
				builder.setTitle(R.string.apagar_movimentacoes);
			} else {
				builder.setTitle(R.string.apagar_movimentacao);
				builder.setMessage(R.string.confirmar_remocao);
			}

			builder.setCancelable(false);
			builder.setPositiveButton(R.string.sim,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							// Toast.makeText(getActivity(),"Got click: " + item
							// + " - " + despesa.getDescricao(),
							// Toast.LENGTH_SHORT).show();
							try {
								if (despesa != null) {
									if (todas.isChecked()) {
										repositorioDespesa.excluir(despesa,
												true);
									} else {
										if (frente.isChecked()) {
											repositorioDespesa.excluir(despesa,
													despesa.getData());
										} else {
											if (!despesa.isPai()) {
												repositorioDespesa
														.excluir(despesa);
											} else {
												List<Despesa> filhos = new ArrayList<Despesa>(
														despesa.getFilhos());
												if (filhos.size() > 0) {
													Despesa novoPai = filhos
															.get(0);
													repositorioDespesa
															.excluir(despesa);

													novoPai.setPai(null);
													repositorioDespesa
															.atualizar(novoPai);
													filhos.remove(novoPai);
													for (Despesa d : filhos) {
														d.setPai(novoPai);
														repositorioDespesa
																.atualizar(d);
													}
												} else {
													repositorioDespesa
															.excluir(despesa);
												}
											}

										}
									}

								}

								if (receita != null) {
									if (todas.isChecked()) {
										repositorioReceita.excluir(receita,
												true);
									} else {
										if (frente.isChecked()) {
											repositorioReceita.excluir(receita,
													receita.getData());
										} else {
											{
												List<Receita> filhos = new ArrayList<Receita>(
														receita.getFilhos());
												if (filhos.size() > 0) {
													Receita novoPai = filhos
															.get(0);
													repositorioReceita
															.excluir(receita);
													novoPai.setPai(null);
													repositorioReceita
															.atualizar(novoPai);
													filhos.remove(novoPai);
													for (Receita d : filhos) {
														d.setPai(novoPai);
														repositorioReceita
																.atualizar(d);
													}
												} else {
													repositorioReceita
															.excluir(receita);
												}

											}
										}
									}
								}

								if (poupanca != null) {
									repositorioPoupanca.excluir(poupanca);
								}

								// expListAdapter.setMesesTotais(getValores());
								// expListAdapter.notifyDataSetChanged();
								Toast.makeText(getActivity(),
										R.string.excluidos_sucesso,
										Toast.LENGTH_LONG).show();
								mListener.onChange(true);
								setChanged(true);
								// loadData();

							} catch (SQLException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}

						}
					});
			builder.setNegativeButton(R.string.nao,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							dialog.cancel();
						}
					});
			AlertDialog alertDialog = builder.create();
			alertDialog.show();

			mode.finish();
			return true;
		}
	}

	public void onAttach(Activity activity) {
		try {
			super.onAttach(activity);
			this.mListener = (OnChangeListener) activity;

		} catch (final ClassCastException e) {
			throw new ClassCastException(activity.toString()
					+ " must implement OnChangeListener");
		}
	}
}
